/*
 * fifo.c
 *
 *  Created on: Jul 20, 2021
 *      Author: fanlida
 */
 
#include <stdio.h>
#include <string.h>
#include "fifo.h"
//#include "printf.h"

/*******************************************************************************
1. fifo_init 初始化 FIFO
2. fifo_len 获得 FIFO 里的数据的长度
3. fifo_size 获得 FIFO 的容量（即 FIFO 的缓冲区的大小）
4. fifo_is_empty 判断 FIFO 是否为空
5. fifo_is_full	判断 FIFO 是否为满
6. fifo_put 将数据写入 FIFO
7. fifo_get 从 FIFO 读出数据
*******************************************************************************/	


/*******************************************************************************
 * 函数名称: fifo_init
 * 函数功能: 初始化 FIFO
 * 入口参数: f:			FIFO 的指针，不能为空指针
 *			 queuelist:	FIFO 的缓冲区基地址，不能为空指针
 *			 size:		FIFO 的缓冲区的大小
 * 出口参数: 0 失败  1 成功
 * 注意事项: f 不能为空指针
*******************************************************************************/	
unsigned char fifo_init(fifo_t *f, unsigned char *queuelist, unsigned int size)
{
	if(queuelist == NULL)	return FALSE;
	f->list			= queuelist;		//添加fifo使用的缓冲区内存地址
	f->pwrite		= 0;				//写指针
	f->pread		= 0;				//读指针
	f->size			= size;				//fifo缓冲区大小
	memset(f->list, 0, f->size);		//缓冲区清零
	return TURE;
}

/*******************************************************************************
 * 函数名称: fifo_len
 * 函数功能: 获得 FIFO 里的数据的长度
 * 入口参数: f:			FIFO 的指针，不能为空指针
 * 出口参数: FIFO 里的数据的长度
 * 注意事项: f 不能为空指针
*******************************************************************************/	
unsigned int fifo_len(const fifo_t *f)
{
	unsigned int len = 0;	

	if(0 == ((f->pwrite + 1) % f->size))
		len = f->size - f->pread;
	else
		len = (f->pwrite % f->size) - f->pread;	
#ifdef 	__PRINTF_H__
	user_debug("fifo_len = %d", len);
#endif
	return len;
}

/*******************************************************************************
 * 函数名称: fifo_size
 * 函数功能: 获得 FIFO 的容量（即 FIFO 的缓冲区的大小）
 * 入口参数: f:			FIFO 的指针，不能为空指针
 * 出口参数: FIFO 的容量
 * 注意事项: f 不能为空指针
*******************************************************************************/	
unsigned int fifo_size(const fifo_t *f)
{
#ifdef 	__PRINTF_H__
	user_debug("fifo_size = %d", f->size);
#endif
	return(f->size);
}

/*******************************************************************************
 * 函数名称: fifo_is_empty
 * 函数功能: 判断 FIFO 是否为空
 * 入口参数: f:			FIFO 的指针，不能为空指针
 * 出口参数: 1 : 空；0: 不空，有数据
 * 注意事项: f 不能为空指针
*******************************************************************************/
unsigned char fifo_is_empty(const fifo_t *f)
{
	if(f->pread == (f->pwrite % f->size) )	return TURE;
	else									return FALSE;
}

/*******************************************************************************
 * 函数名称: fifo_is_full
 * 函数功能: 判断 FIFO 是否为满
 * 入口参数: f:			FIFO 的指针，不能为空指针
 			 len:		待加入的数据长度	例：len = 4 表示 再加入4个元素是否会满
 * 出口参数: 1 : 满；0: 不满，有空位
 * 注意事项: f 不能为空指针
*******************************************************************************/
unsigned char fifo_is_full(const fifo_t *f)
{
	//查看写指针后一位是不是读指针
	if((f->pwrite + 1) % f->size == f->pread)	return TURE;
	else										return FALSE;
}


/*******************************************************************************
 * 函数名称: fifo_put
 * 函数功能: 将数据写入 FIFO
 * 入口参数: f:			FIFO 的指针，不能为空指针
 *			 buf:		需要写入的数据的缓冲区基地址，不能为空指针
 *			 len:		需要写入的数据的长度
 * 出口参数: 实际写入 FIFO的数据长度
 * 注意事项: f 不能为空指针
*******************************************************************************/

unsigned int fifo_put(fifo_t *f, unsigned char *buf, unsigned int len)
{
	unsigned int i;
	//添加判断语句，如果pwrite超过size，则直接将其从0重新开始存储，
    //如果rear+1和front重合，则表示数组已满
    //printf("enQueue  data = %d, len = %d \n", *data, len);
    if(fifo_is_full(f) == TURE)
	{
#ifdef 	__PRINTF_H__
		user_debug("fifo is full!");
#endif
        return 0;
	}
	
	for(i = 0; i < len; i++)
	{
#ifdef 	__PRINTF_H__
		user_debug("%02x ", buf[i]);
#endif
		f->list[f->pwrite % f->size] = buf[i];
		if(fifo_is_full(f) == TURE)
		{
#ifdef 	__PRINTF_H__
			user_debug("fifo is full!");
#endif
			return (i + 1);
		}
		
		f->pwrite ++;
	}
#ifdef 	__PRINTF_H__
	user_debug("fifo_put %d\n", len);
#endif
    return len;
}


/*******************************************************************************
 * 函数名称: fifo_get
 * 函数功能: 从 FIFO 读出数据
 * 入口参数: f:			FIFO 的指针，不能为空指针
 *			 buf:		用于存放读出的数据的缓冲区基地址，不能为空指针
 *			 len:		需要读出的数据的长度
 * 出口参数: 实际读出的数据的长度
 * 注意事项: f 不能为空指针
*******************************************************************************/
unsigned int fifo_get(fifo_t *f, unsigned char *buf, unsigned int len)
{                                
	unsigned int i;
	if( fifo_is_empty(f) == TURE) return 0;
	for(i = 0; i < len; i++)
	{
		buf[i] = f->list[f->pread];     		
  	
		if(fifo_is_empty(f) == TURE)
		{
#ifdef 	__PRINTF_H__
			user_debug("fifo is empty!");
#endif
			f->pwrite		= 0;
			f->pread		= 0;
			return (i + 1);
		}
		f->pread = (f->pread + 1) % f->size;
	}
    return len;
}



